package com.indigon.petri.model
{
	import com.indigon.petri.data.ArenaData;
	import com.indigon.petri.model.hex.Hex;
	import com.indigon.petri.model.hex.HexCoords;
	import com.indigon.petri.model.hex.HexDirection;
	import com.indigon.petri.model.hex.HexUtils;

	public class Model
	{
		public static const EMPTY_PLAYER : uint = 0;
		public static const NO_FILL      : uint = 0;
		
		public var orbits : Vector.<Vector.<Hex>>;
		public var counts : Vector.<uint>;
		
		public var updatedHexes : Vector.<Hex>;
		
		public function Model() 
		{
		}
		
		public function configure(data:ArenaData):void
		{
			// set hexes in orbits and slots.
			orbits = new Vector.<Vector.<Hex>>(data.orbits);
			for (var orbit : uint = 0; orbit < data.orbits; orbit++)
			{
				var slots : uint = HexUtils.slotsPerOrbit(orbit);
				orbits[orbit] = new Vector.<Hex>(slots);
				
				for (var slot : uint = 0; slot < slots; slot++)
				{
					orbits[orbit][slot] = new Hex(orbit, slot, this);
				}
			}
			
			// configure enviornments for first orbits. 
			for (var dir : uint = 0; dir < 6; dir++)
			{
				var oHex : Hex = orbits[1][(dir + 2) % 6]
				orbits[0][0].env[dir] = oHex;
				oHex.env[HexDirection.COUNTER_OF[dir]] = orbits[0][0];
			}
			
			// configure enviornments. 
			for (orbit = 1; orbit < data.orbits; orbit++)
			{
				for (slot = 0; slot < orbits[orbit].length; slot++)
				{
					var hex : Hex  = orbits[orbit][slot];
					var seg : uint = HexUtils.getSegement(orbit, slot);
					
					// set enviornment within orbit.
					oHex = orbits[orbit][HexUtils.getSlot(orbit, slot + 1)];
					hex.env[seg] = oHex;
					oHex.env[HexDirection.COUNTER_OF[seg]] = hex;
					
					// set inner enviornment.
					if (orbit > 1)
					{
						oHex = orbits[orbit - 1][HexUtils.getSlot(orbit - 1, slot - seg)];
						var innerDir : uint = (seg + 1) % 6;
						hex.env[innerDir] = oHex;
						oHex.env[HexDirection.COUNTER_OF[innerDir]] = hex;
					}
					
					// set exterior enviornment.
					if (orbit < (data.orbits - 1))
					{
						oHex = orbits[orbit + 1][HexUtils.getSlot(orbit + 1, slot + seg + 1)];
						var outerDir : uint = (seg + 5) % 6;
						hex.env[outerDir] = oHex;
						oHex.env[HexDirection.COUNTER_OF[outerDir]] = hex;
					}
				}
			}
			
			// configure blocks.
			for each (var block : HexCoords in data.blocks)
			{
				orbits[block.orbit][block.slot].isBlock = true;
			}
			
			// configure players.
			counts = new Vector.<uint>(data.players.length);
			for (var pl : uint = 0; pl < data.startPos.length; pl++)
			{
				var pos : HexCoords = data.startPos[pl];
				orbits[pos.orbit][pos.slot].player = pl + 1;
				orbits[pos.orbit][pos.slot].value = data.players[pl].baseFillValue;
				counts[pl] = 1;
			}
		}
		
		public function reset():void
		{
			for (var orbit : uint = 0; orbit < orbits.length; orbit++)
			{
				for (var slot : uint = 0; slot < orbits[orbit].length; slot++)
				{
					orbits[orbit][slot].uninit()
				}
			}

			orbits = null;
			counts = null;
			updatedHexes = null;
		}
		
		public function update():void
		{
			var i : uint;
		}
	}
}